﻿namespace Softserve.Pottery.Infrastructure.Serialization
{
    using System;
    using System.Web.Script.Serialization;
    using System.Xml;

    /// <summary>
    /// <code>
    /// 
    ///[Serializable]
    ///[System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:example-object")]
    ///public class Example
    ///{
    ///    [System.Xml.Serialization.XmlAttribute(AttributeName = "id")]
    ///    public int ObjectID { get; set; }
    ///    [System.Xml.Serialization.XmlElement("Name", typeof(string))]
    ///    public string Name { get; set; }
    ///    [System.Xml.Serialization.XmlElement("description", typeof(string))]
    ///    public string Description { get; set; }
    ///}
    /// </code>
    /// </summary>
    public class SerializationHelper
    {
        public static System.Data.SqlTypes.SqlXml XmlSeralize<T>(T value)
        {
            /// Check the argument value
            if (!(value is T))
            {
                throw new ArgumentNullException("value");
            }

            //System.Data.SqlTypes.SqlXml element = null;
            using (System.IO.Stream memory = new System.IO.MemoryStream())
            {
                System.Xml.Serialization.XmlSerializer xmlf = new System.Xml.Serialization.XmlSerializer(typeof(T));
                xmlf.Serialize(memory, value);
                memory.Flush();
                memory.Position = 0;
                return new System.Data.SqlTypes.SqlXml(XmlReader.Create(memory));
            }
        }

        public static T XmlDeserialize<T>(System.Data.SqlTypes.SqlXml value)
        {
            /// Check the argument value
            if ((value == null || value.IsNull))
            {
                throw new ArgumentNullException("value");
            }

            System.Xml.Serialization.XmlSerializer xmlf = new System.Xml.Serialization.XmlSerializer(typeof(T));

            return (T)xmlf.Deserialize(value.CreateReader());
        }

        public static System.Data.SqlTypes.SqlBytes BinarySerialize<T>(T value)
        {
            /// Check the argument value
            if (!(value is T))
            {
                throw new ArgumentNullException("value");
            }

            using (System.IO.Stream memory = new System.IO.MemoryStream())
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                bf.Serialize(memory, value);
                memory.Flush();
                memory.Position = 0;
                return new System.Data.SqlTypes.SqlBytes(memory);
            }
        }

        public static T BinaryDeserialize<T>(System.Data.SqlTypes.SqlBytes value)
        {
            /// Check the argument value
            if (value == null || value.IsNull)
            {
                throw new ArgumentNullException("value");
            }

            ///If array is empty then return default value for these data type
            if (value.Length < 1)
            {
                return default(T);
            }

            using (System.IO.MemoryStream memory = new System.IO.MemoryStream())
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                return (T)bf.Deserialize(memory);
            }
        }

        public static string JSONSerialize(object value)
        {
            if (value == null)
            {
                throw new NullReferenceException();
            }
            
            JavaScriptSerializer s = new JavaScriptSerializer();

            return s.Serialize(value);            
        }

        public static T JSONSerialize<T>(string value)
        {
            if (value == null)
            {
                throw new NullReferenceException();
            }
            if (string.IsNullOrEmpty(value))
            {
                throw new ArgumentNullException();
            }

            JavaScriptSerializer s = new JavaScriptSerializer();

            T obj = s.Deserialize<T>(value);

            return obj;
        }
    }
}
